from DrissionPage import Chromium, ChromiumOptions, SessionOptions
from DrissionPage.common import Settings
from email_permission import email_list
import json
import requests

def return_headers(account_id=None):
    return {
        "accept": "application/json, text/plain, */*",
        "accept-language": "zh-CN,zh;q=0.9",
        "content-type": "application/json",
        "origin": "https://ad.xiaohongshu.com",
        "priority": "u=1, i",
        "referer": f"https://ad.xiaohongshu.com/aurora/ad/create2?from=CampaignList&vSellerId={account_id}",
        "sec-ch-ua": "\"Google Chrome\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
        "v-seller-id": f"{account_id}",
        "x-b3-traceid": "0b1604e0c37f7021"
}

def return_post_headers(account_id=None):
    return {
        "accept": "application/json, text/plain, */*",
        "accept-language": "zh-CN,zh;q=0.9",
        "content-type": "application/json",
        "origin": "https://ad.xiaohongshu.com",
        "priority": "u=1, i",
        "referer": f"https://ad.xiaohongshu.com/aurora/ad/tools/targetPackage/create?vSellerId={account_id}",
        "sec-ch-ua": "\"Google Chrome\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
        "v-seller-id": f"{account_id}",
        "x-b3-traceid": "039da9491202516e",
        "x-s-common": "2UQAPsHC+aIjqArjwjHjNsQhPsHCH0rjNsQhPaHCH0c1PahFHjIj2eHjwjQgynEDJ74AHjIj2ePjwjQY4gQ6qfrTq9YSJBIjNsQh+sHCH0H1Pshl+/cjNsQh+aHCH0rE+0mSPfb08nGF8gGIP0mY8BQlGf4h8B+IqAWhqBYj4nTCGnQ1Gnkf+/ZIPeZU+AHUweZjNsQh+jHCHjHVHdW7H0ijHjIj2eWjwjQQPAYUaBzdq9k6qB4Q4fpA8b878FSet9RQzLlTcSiM8/+n4MYP8F8LagY/P9Ql4FpUzfpS2BcI8nT1GFbC/L88JdbFyrSiafp/8DMra7pFLDDAa7+8J7QgabmFz7Qjp0mcwp4fanD68p40+fp8qgzELLbILrDA+9p3JpH9LLI3+LSk+d+DJfpSL98lnLYl49IUqgcMc0mrcDShtMmozBD6qM8FyFSh8o+h4g4U+obFyLSi4nbQz/+SPFlnPrDApSzQcA4SPopFJeQmzBMA/o8Szb+NqM+c4ApQzg8Ayp8FaDRl4AYs4g4fLomD8pzBpFRQ2ezLanSM+Skc47Qc4gcMag8VGLlj87PAqgzhagYSqAbn4FYQy7pTanTQ2npx87+8NM4L89L78p+l4BL6ze4AzB+IygmS8Bp8qDzFaLP98Lzn4AQQzLEAL7bFJBEVL7pwyS8Fag868nTl4e+0n04ApfuF8FSbL7SQyrpdL/4Q8DShzgPh/nlTanT08fQc4M+Qc7bgwB4tqMSC/7+3Lo4aa/+N8n8scnpDPec3aLL98/8jJLzNpd4DanTN8/+d4d+nJaRAPpmF/dZ6/9px4g4nag8b87iIPBpfpd4p/rH7qFzM4FQQPM+Ya/+T+nMM4F4TLo4tJFbk+rTg/fpr8ApS+db7GFSi8g+r+A8SPgkawLSb/d+f/npA+fk0JrS3/fLALozLanSjPoSc4omtLo4DagYS8nSn4r8Qz/mApop7LFSiN7+r4gz/47p7q9Rn4bYQ4DYpa/+Qq/zYqbQzzB4AP7bFcFShJLMQyFkAzobFqLlrt9b6PemA8emH8DSkqDQo4gz6qdp7yrS98BphqgzM/FzS8/+VPoPlGfMOanYwqM8DPo+kqgzANM87qLDAcnLIqg49anTd8/8A4gQQ4DESzB8t8/mc4BlQ2e8Ay7b780YfwbbQzLYSag8SqAb++fph+78AnLzmqM+c4okQyFIlagY3ngQn4AzQcFppanYdq9TB+BcFGDTSydp7+rShyBbCpd4//9HI8LzVJ7+hpdzkPSmF+DSkaeYQ4fTbLobF4npl4AmQyURA+fLA8nzn4AbEqgz9ag8TaaTM4eQQy7HALb4y2rS38g+fw/4A8BqM8p8l4UTH4gzFagYi2LSh8gPApdc9aLL98p+jJBlQc9QycS48/DS9prYQ4DESLMm7PBEl4okFpdzpagYHnrSi8g+h8/8SpSm7pob/nfzQc9WhzM8Fa9Mn4r4QP9YGagYL8FSkLDzQyrRSyFGAqAb/LLTcLo4oag8QLjRn4URjpd4manYN8/bspAbQyFY989R68/8c4e4TpdcFcSkHGnpDqp8Qy9TbGp87nDS3+dPIpMStanT/2nRc478QyMH34opFLFQc4BMQyrSxag8L+LSi2DEAqg4aanSn4FSb8oPA4g4g8nbTcLSizfRQc9RApASmqA+l4M4QcAzEaL+Pzfbg4L+Q40WlGnbiprS9cg+8qsRSPob74FSecg+3pdzPanYy2LSePo+8LoqAanYzPdzl4FRQcFkAyp4MnjRn4rG3pdzAa/+d8n8l4o4Qz/mApFzjyDS3+g+fq0+APp8FGFW6cg+gpd4wqr8SqM8n4eYQ2rRA8d+m8nSM4rpQybk9anSH87Qn47+NG7k1a/+O8nkM49EUNFkSP9lVngQM4omQynQwanD9q98QJpkQ2rRSzb8FPFS9ygSQznzSzrMaPrSiaBzQygQjz7QC4FSbJ9pDnL8paL++8rSh4/bQcFEAn/mB4FYyO/FjNsQhwaHCP/cUPAGl+/r7+jIj2erIH0iINsQhP/rjwjQVygzSHdF="
}





def log_message(log_callback, message, color=None):
    if callable(log_callback):
        log_callback(message, color) if color else log_callback(message)
def open_jg_page(account_id, log_callback=None):
    Settings.set_language("zh_cn")
    co = ChromiumOptions(read_file=False)  # 不读取文件方式新建配置对象
    so = SessionOptions(read_file=False)
    browser = Chromium(addr_or_opts=co, session_options=so)

    # 打开合作伙伴平台页面
    account_tab = browser.new_tab('https://partner.xiaohongshu.com/partner/subAccount-list')
    log_message(log_callback, f'正在登录聚光后台获取cookie, 请稍候', "green")

    # TODO 加一个校验步骤， 不是叁柒的所属邮箱直接驳回
    account_tab.ele('tag:span@@class=d-text --color-static --color-text-paragraph --size-text-paragraph text label@@text()^登陆邮箱：').next().child().next().click(by_js=True)
    account_tab.wait(0.5)
    email_str = account_tab.ele('tag:span@@class=d-text --color-static --color-text-paragraph --size-text-paragraph text label@@text()^登陆邮箱：').next().child().text
    email_permission_list = email_list(log_callback)
    if email_str not in email_permission_list:
        log_message(log_callback, f"当前邮箱账号:【{email_str}】暂无权限使用", "red")
        return

    account_tab.ele('tag:input@@class=el-input__inner@@type=text@@autocomplete=off@@placeholder=请输入').click()
    account_tab.ele('tag:input@@class=el-input__inner@@type=text@@autocomplete=off@@placeholder=请输入').input(account_id)
    account_tab.ele('tag:button@@id=search-btn--1').click(by_js=True)

    account_tab.wait(2)

    search_none_ele = account_tab.ele('tag:tr@@class=d-table__empty-row@@text()=暂无数据', timeout=0.5)
    if search_none_ele:
        log_message(log_callback, f"合作伙伴平台子账号ID:{account_id}搜索结果为空, 检查表格第一行子账号ID, 或者检查是否登录合作伙伴平台", "red")
        return

    account_tab.ele('tag:span@@text():跳转', timeout=2).hover()
    jg_ele = account_tab.ele('tag:span@@class=d-text --color-static --color-current --size-text-paragraph d-text-nowrap d-text-ellipsis@@text():聚光平台', timeout=2)

    if jg_ele:
        create_plan_tab = jg_ele.click.for_new_tab(by_js=True)
        create_plan_tab.wait.title_change("计划列表")
        unit_dict_cookie = create_plan_tab.cookies(all_info=False).as_dict()
        log_message(log_callback, f'获取cookie完成, 正在获取关联包等动态数据...', "green")
        return unit_dict_cookie


def find_name_by_code(tree_data, target_code):
    """
    根据 code 在树形结构中查找对应的 name
    :param tree_data: 树形结构数据（列表）
    :param target_code: 要查找的 code
    :return: 对应的 name，如果找不到返回 None
    """
    for node in tree_data:
        if node['code'] == target_code:
            return node['name']

        if 'children' in node and node['children']:  # 递归查找
            result = find_name_by_code(node['children'], target_code)
            if result is not None:
                return result
    return None  # 遍历完整个树都没找到，返回 None



def get_indus_category_tree(cookies=None, account_id=None, taxonomy_code=None): # 行业类目树形图
    tree_url = "https://ad.xiaohongshu.com/api/leona/spu/taxonomy/tree"  # 行业类目树形图路径

    headers = return_headers(account_id=account_id)
    response = requests.get(tree_url, headers=headers, cookies=cookies)
    res_json = response.json()

    taxonomy_name = "分类不存在"
    if res_json and res_json.get('code') == 0:
        tree_data = res_json.get('data', {})
        taxonomy_name = find_name_by_code(tree_data, taxonomy_code)

    return taxonomy_name

def collect_relative_pack_list_exists(cookies=None, account_id=None, log_callback=None):
    relative_pack_url = "https://ad.xiaohongshu.com/api/leona/rtb/target/template/query"  # 关联定向包路径

    data = {
        "page": 1,
        "pageSize": 999,
        "placement": 1,
    }

    headers = return_headers(account_id=account_id)
    data = json.dumps(data, separators=(',', ':'))
    response = requests.post(relative_pack_url, headers=headers, cookies=cookies, data=data)
    res_json = response.json()

    target_name_packages = []
    if res_json and res_json.get('code') == 0:
        relative_list = res_json.get('data', {}).get('list', [])
        target_name_packages = [{'id': item['id'], 'name': item['name']} for item in relative_list if 'id' in item and 'name' in item]

    return target_name_packages


def crawl_save_target_package(cookies=None, account_id=None, data=None):
    copy_package_url = "https://ad.xiaohongshu.com/api/leona/rtb/target/template/add"

    headers = return_post_headers(account_id=account_id)
    data = json.dumps(data, separators=(',', ':'))

    response = requests.post(copy_package_url, headers=headers, cookies=cookies, data=data)
    res_json = response.json()

    return res_json



def collect_recom_spu_list_exists(cookies=None, account_id=None, log_callback=None):
    spu_url = "https://ad.xiaohongshu.com/api/leona/spu/list/searchAdsData"  # SPU路径

    data = {
        "startTime": "2025-06-25",
        "endTime": "2025-06-19",
        "name": "",
        "type": 2,
        "pageNum": 1,
        "pageSize": 999,
        "orderClauses": [],
        "retail": "0"
    }
    headers = return_headers(account_id=account_id)
    data = json.dumps(data, separators=(',', ':'))
    response = requests.post(spu_url, headers=headers, cookies=cookies, data=data)
    res_json = response.json()

    spu_name_list = []
    if res_json and res_json.get('code') == 0:
        spu_list = res_json.get('data', {}).get('list', [])
        spu_name_list = [{"spuName": item['spuName'], "taxonomyCode": item['taxonomyCode']} for item in spu_list if 'spuName' in item and item['spuAttributeAuditState'] == '审核通过']

    return spu_name_list


def collect_relative_pack_details_id(cookies=None, account_id=None, pkg_id=None):
    url = "https://ad.xiaohongshu.com/api/leona/rtb/target/template/query"

    data = {
        "id": pkg_id,
        "page": 1,
        "pageSize": 10
    }

    headers = return_headers(account_id=account_id)
    data = json.dumps(data, separators=(',', ':'))
    response = requests.post(url, headers=headers, cookies=cookies, data=data)
    res_json = response.json()

    targetConfig = {}
    if res_json and res_json.get('code') == 0:
        pkg_list = res_json.get('data', {}).get('list', [])
        if pkg_list:
            targetConfig = pkg_list[0]
        else:
            targetConfig = {}  # 或者 None，根据你的业务逻辑处理

    return targetConfig
